package presenter.flat;

import main.InputBean;
import main.InputMode;
import utils.OnLogListener;
import utils.FileBean;
import utils.FileFilter;
import utils.TextUtils;
import utils.ThreadPool;

import java.io.File;
import java.util.*;

public class DirFlater {
    private static final int MAX_LOG_SIZE = 100;
    private String path;
    private InputMode mode;
    private OnLogListener listener;
    private List<FileBean> dirs = new ArrayList<>();

    public static void flat(InputBean info, OnLogListener listener) {
        ThreadPool.work(() -> {
            DirFlater flater = new DirFlater();
            flater.path = info.path1();
            flater.mode = info.mode();
            flater.listener = listener;
            flater.action();
        });
    }

    private void action() {
        dirs.clear();

        collectDir(() -> collectFile(() -> delEmptyDir(() -> listener.taskFinish())));
    }

    private void collectDir(Runnable next) {
        if (justOnce()) {
            File file = new File(path);
            FileBean dir = FileBean.newInstance(file);
            dirs.add(dir);
            next.run();
        } else {
            List<FileBean> items = FileFilter.filter(true, true, false, path, name -> true);
            if (items != null && !items.isEmpty()) {
                dirs = items;
                next.run();
            } else {
                log("暂未发现文件,任务结束!");
                listener.taskFinish();
            }
        }
    }

    private void collectFile(Runnable next) {
        int size = dirs.size();
        int index = 0;
        log(String.format("总共需要整理 %d 个文件夹,请稍等....", size));

        for (FileBean item : dirs) {
            index++;
            String path = item.path();
            List<FileBean> items = sub(item);

            log(String.format("%s 文件夹【整理】完毕，准备移动文件...", path));

            move(path, items);
            log(String.format("%s 文件夹【移动】完毕，还剩 %d 个文件夹待分析!", path, (size - index)));

            if (items != null) {
                items.clear();
            }
        }
        next.run();
    }

    private List<FileBean> sub(FileBean dir) {
        String path = dir.path();
        List<FileBean> items = FileFilter.filter(true, path, name -> true);
        if (items != null && !items.isEmpty()) {
            Iterator<FileBean> iterator = items.iterator();
            while (iterator.hasNext()) {
                FileBean item = iterator.next();
                if (TextUtils.equals(item.parent(), path)) {
                    iterator.remove();
                }
            }
        }
        return items;
    }

    private void move(String path, List<FileBean> items) {
        if (items == null || items.isEmpty()) {
            log(String.format("%s 文件夹为空", path));
        } else {
            int size = items.size();
            boolean toLarge = size > MAX_LOG_SIZE;
            if (toLarge) {
                listener.log(String.format("该文件夹共【%d】个文件需要移动，总数过多，不展示移动细节！", size));
            }
            for (FileBean item : items) {
                item.move(path, toLarge ? null : listener);
            }
        }
    }

    private void delEmptyDir(Runnable next) {
        FileFilter.delEmptyDir(path);
        next.run();
    }

    private boolean justOnce() {
        return mode == InputMode.FlatDir;
    }

    private void log(String content) {
        listener.log(content);
    }
}
